#ifndef KERNEL_MULTIBOOT_H
#define KERNEL_MULTIBOOT_H

#include <Mint/Types.h>

#ifdef _cplusplus
extern "C" {
#endif

typedef struct MultibootHeader_s MultibootHeader_t;
typedef struct MultibootInfo_s MultibootInfo_t;
typedef struct MultibootModule_s MultibootModule_t;
typedef struct MultibootMemoryMap_s MultibootMemoryMap_t;
typedef struct MultibootDrive_s MultibootDrive_t;
typedef struct MultibootApmTable_s MultibootApmTable_t;

struct MultibootHeader_s
{
	uint32 fSignature;
	uint32 fFlags;
	uint32 fChecksum;
	uint32 fHeaderAddress;
	uint32 fLoadAddress;
	uint32 fLoadEndAddress;
	uint32 fBssEndAddress;
	uint32 fEntryAddress;
};


struct MultibootInfo_s
{
	uint32 fFlags;

	struct
	{
		uint32 fLower;
		uint32 fUpper;
	} fMemory;

	struct
	{
		uint8 fPartition3;
		uint8 fPartition2;
		uint8 fPartition1;
		uint8 fDrive;
	} fBootDevice;

	uint32 fCommandLine;

	struct
	{
		uint32 fCount;
		uint32 fBaseAddress;
	} Modules;

	union
	{
		struct
		{
			uint32 fTableSize;
			uint32 fStringSize;
			uint32 fAddress;
			uint32 __reserved;
		} fAoutSymbol;
		struct
		{
			uint32 fNumber;
			uint32 fSize;
			uint32 fAddress;
			uint32 fShndx;
		} fElfSectionHeader;
	};

	struct
	{
		uint32 fLength;
		uint32 fBaseAddress;
	} fMemoryMap;

	struct
	{
		uint32 fLength;
		uint32 fBaseAddress;
	} fDrives;

	uint32 fConfigTable;
	uint32 fBootLoaderName;
	uint32 fApmTable;

	struct
	{
		uint32 fControlInfo;
		uint32 fModeInfo;
		uint16 fMode;

		struct
		{
			uint16 fSegment;
			uint16 fOffset;
			uint16 fLength;
		} fInterface;
	} fVbe;
};


struct MultibootModule_s
{
	uint32 fBaseAddress;
	uint32 fEndAddress;
	uint32 fString;
	uint32 __reserved;
};


struct MultibootMemoryMap_s
{
	uint32 fSize;
	uint16 fBaseAddress;
	uint16 fLength;
	uint32 fType;
};

struct MultibootDrive_s
{
	uint32 fSize;
	uint8 fNumber;
	uint8 fMode;
	uint16 fCylinders;
	uint8 fHeads;
	uint8 fSectors;
	uint16 * fPorts;
};

struct MultibootApmTable_s
{
	uint16 fVersion;
	uint16 fCodeSegment;
	uint16 fOffset;
	uint16 fCodeSegment16;
	uint16 fDataSegment;
	uint16 fCodeSegmentLength;
	uint16 fCodeSegment16Length;
	uint16 fDataSegmentLength;
};

#ifdef _cplusplus
}
#endif

KernelArgs_t * Multiboot_PrepareArgs( MultibootInfo_t * info );

#endif // KERNEL_MULTIBOOT_H
